#ifndef __BL_OBJECTPOOL_H__
#define __BL_OBJECTPOOL_H__

#include "../PreInclude.h"

namespace BlEngine
{ 
	template<typename T>
	class ObjectPool
	{
	public:
		ObjectPool(size_t unSize)
		: m_count(unSize)
		{
			for (size_t i = 0; i < m_count; ++i)
				m_list.push_back(new T);
		}
	 
		~ObjectPool()
		{
			typename std::list<T *>::iterator iter = m_list.begin();
			while (iter != m_list.end())
			{
				if(NULL != *iter)
				{
					delete (*iter);
					*iter = NULL;
				}
				++iter;
			}
			m_count = 0;
		}
	 
		T * GetObject()
		{
			T * pObj = NULL;
			if (0 == m_count)
			{
				pObj = new T;
			}
			else
			{
				pObj = m_list.front();
				m_list.pop_front();
				--m_count;
			}
	 
			return pObj;
		}
	 
		void ReturnObject(T * pObj)
		{
			m_list.push_back(pObj);
			++m_count;
		}
	 
        std::list<T *> m_list;
	private:
		size_t m_count;
		
	};
    
    
    
    
    template<typename T>
	class CCObjectPool
	{
	public:
		CCObjectPool(size_t unSize)
		: m_count(unSize)
		{
			for (size_t i = 0; i < m_count; ++i)
            { 
				T * pObj = T::create();
                pObj->retain();
				m_list.push_back(pObj);
            }
		}
        
		~CCObjectPool()
		{
			typename std::list<T *>::iterator iter = m_list.begin();
			while (iter != m_list.end())
			{
				if(NULL != *iter)
				{
					(*iter)->release();
				}
				++iter;
			}
            m_list.clear();
			m_count = 0;
		}
        
		T * GetObject()
		{
			T * pObj = NULL;
			if (0 == m_count)
			{
				pObj = T::create();
                pObj->retain();
			}
			else
			{
				pObj = m_list.front();
				m_list.pop_front();
				--m_count;
			}
            
			return pObj;
		}
        
		void ReturnObject(T * pObj)
		{
			m_list.push_back(pObj);
			++m_count;
		}
        
	private:
		size_t m_count;
		std::list<T *> m_list;
	};
};


#endif